home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / usespheremap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.3 KB  |  253 lines

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <GL/glut.h>
  7. #include "texture.h"
  8.  
  9. #ifndef __sgi
  10. #define trunc(x) ((double)((int)(x)))
  11. #endif
  12.  
  13. GLsizei sphereTexW, sphereTexH, padSphereTexW, padSphereTexH;
  14. GLint sphereTexComp;
  15.  
  16.  
  17. const char defaultSphereMap[] = "data/spheremap.rgb";
  18. int drawTorus = 1;
  19.  
  20.  
  21. int roundup(int n)
  22. {
  23.   int val = 1;
  24.   while (val < n) val <<= 1;
  25.   return val;
  26. }
  27.  
  28. void create_texture(const char *fname, GLsizei *w,  GLsizei *h, 
  29.               GLsizei *padW, GLsizei *padH, GLint *comps)
  30. {
  31.   GLuint *img, *padImg = NULL;
  32.   int y;
  33.  
  34.   img = read_texture(fname, w, h, comps);
  35.   if (!img) {
  36.     fprintf(stderr, "Could not open %s\n", fname);
  37.     exit(1);
  38.   }
  39.  
  40.   /* if width & height are not powers of two, pad image with black */
  41.   if (*w & (*w - 1)) {
  42.     *padW = roundup(*w);
  43.   } else {
  44.     *padW = *w;
  45.   }
  46.   if (*h & (*h - 1)) {
  47.     *padH = roundup(*h);
  48.   } else {
  49.     *padH = *h;
  50.   }
  51.  
  52.   if (*padW != *w || *padH != *h) {
  53. printf("rounding %s up...\n", fname);
  54.     padImg = (GLuint *)malloc(*padW * *padH * sizeof(GLuint));
  55.     if (!padImg) {
  56.       fprintf(stderr, "Malloc of %d bytes failed.\n", 
  57.           *padW * *padH * sizeof(GLuint));
  58.       exit(1);
  59.     }
  60.     memset(padImg, 0, *padW * *padH * sizeof(GLuint));
  61.     for (y = 0; y < *h; y++) {
  62.       memcpy(&padImg[y * *padW], &img[y * *w], *w * sizeof(GLuint));
  63.     }
  64.   }
  65.  
  66.   /* you should use texture objects here if your system supports them... */
  67. printf("w = %d h = %d\n", *padW, *padH);
  68.   glTexImage2D(GL_TEXTURE_2D, 0, 4, *padW, *padH, 0, 
  69.            GL_RGBA, GL_UNSIGNED_BYTE, img);
  70.  
  71.   free(img);
  72.   if (padImg) free(padImg);
  73. }
  74.  
  75. void init(const char *sphereFile)
  76. {
  77.   static GLfloat lightpos[] = {.5, .75, 1.5, 1};
  78.  
  79.   glEnable(GL_DEPTH_TEST); 
  80.   glEnable(GL_LIGHTING);
  81.   glEnable(GL_LIGHT0);
  82.  
  83.   glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  84.  
  85.     create_texture(sphereFile, &sphereTexW, &sphereTexH, 
  86.            &padSphereTexW, &padSphereTexH, &sphereTexComp);
  87. }
  88.  
  89. void reshape(GLsizei w, GLsizei h) 
  90. {
  91.   glViewport(0, 0, w, h);
  92.   
  93.   glMatrixMode(GL_PROJECTION);
  94.   glLoadIdentity();
  95.   gluPerspective(60, 1, .01, 10);
  96.   gluLookAt(0, 0, 0, 
  97.         0, 0, -1, 
  98.         0, 1, 0);
  99.   
  100.   glMatrixMode(GL_MODELVIEW);
  101.   glLoadIdentity();
  102. }
  103.  
  104. void draw_room(void)
  105. {
  106.   /* material for the walls, floor, ceiling */
  107.   static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  108.  
  109.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  110.  
  111.   glBegin(GL_QUADS);
  112.   
  113.   /* floor */
  114.   glNormal3f(0, 1, 0);
  115.   glVertex3f(-1, -1, 1);
  116.   glVertex3f(1, -1, 1);
  117.   glVertex3f(1, -1, -1);
  118.   glVertex3f(-1, -1, -1);
  119.  
  120.   /* ceiling */
  121.   glNormal3f(0, -1, 0);
  122.   glVertex3f(-1, 1, -1);
  123.   glVertex3f(1, 1, -1);
  124.   glVertex3f(1, 1, 1);
  125.   glVertex3f(-1, 1, 1);  
  126.  
  127.   /* left wall */
  128.   glNormal3f(1, 0, 0);
  129.   glVertex3f(-1, -1, -1);
  130.   glVertex3f(-1, 1, -1); 
  131.   glVertex3f(-1, 1, 1);
  132.   glVertex3f(-1, -1, 1);
  133.  
  134.   /* right wall */
  135.   glNormal3f(-1, 0, 0);
  136.   glVertex3f(1, -1, 1);
  137.   glVertex3f(1, 1, 1);
  138.   glVertex3f(1, 1, -1);
  139.   glVertex3f(1, -1, -1);
  140.  
  141.   /* far wall */
  142.   glNormal3f(0, 0, 1);
  143.   glVertex3f(-1, -1, -1);
  144.   glVertex3f(1, -1, -1);
  145.   glVertex3f(1, 1, -1);
  146.   glVertex3f(-1, 1, -1);
  147.  
  148.   glEnd();
  149.  
  150. }
  151.  
  152. void draw_torus(GLdouble angle)
  153. {
  154.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  155.           GL_NEAREST);
  156.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
  157.           GL_NEAREST);
  158.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  159.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  160.   glEnable(GL_TEXTURE_GEN_S);
  161.   glEnable(GL_TEXTURE_GEN_T);
  162.   glEnable(GL_TEXTURE_2D);  
  163.   glEnable(GL_CULL_FACE); 
  164.   
  165.   glPushMatrix();
  166.   glTranslatef(0, 0, -3);
  167.   glRotatef(angle, 1, 1, 0);
  168.   
  169.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  170.  
  171.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  172.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  173.   
  174.   if (drawTorus) {
  175.     glutSolidTorus(.4, .75, 32, 32);
  176.   } else {
  177.     GLUquadricObj *sphere = gluNewQuadric();
  178.     gluSphere(sphere, 1, 32, 32);
  179.   }
  180.  
  181.   glDisable(GL_TEXTURE_2D);
  182.   glDisable(GL_TEXTURE_GEN_S);
  183.   glDisable(GL_TEXTURE_GEN_T);
  184.   glEnable(GL_LIGHTING);
  185.   glDisable(GL_CULL_FACE);
  186.  
  187.   glPopMatrix();
  188. }
  189.  
  190. GLdouble get_secs(void)
  191. {
  192.   return glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  193. }
  194.  
  195. void draw(void)
  196. {
  197.     GLenum err;
  198.     GLdouble secs, degrees;
  199.  
  200.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  201.  
  202.     /* one revolution every 10 seconds... */
  203.     secs = get_secs();
  204.     secs = secs - 10.*trunc(secs / 10.);
  205.     degrees = (secs/10.) * (360.);
  206.  
  207. #if 0
  208.     draw_room();
  209. #endif
  210.     draw_torus(degrees);
  211.  
  212.     err = glGetError();
  213.     if (err != GL_NO_ERROR) printf("Error:  %s\n", gluErrorString(err));
  214.  
  215.     glutSwapBuffers();
  216. }
  217.  
  218. /* ARGSUSED1 */
  219. void key(unsigned char key, int x, int y)
  220. {
  221.   static int idle = 1;
  222.   if (key == 27) exit(0);
  223.   if (key == 'o' || key == 'O') {
  224.     drawTorus = (drawTorus == 0);
  225.     draw();
  226.   } else {
  227.     if (idle) {
  228.       glutIdleFunc(0);
  229.     } else {
  230.       glutIdleFunc(draw);
  231.     }
  232.     idle = (idle == 0);
  233.   }
  234. }
  235.  
  236. main(int argc, char *argv[])
  237. {
  238.     glutInit(&argc, argv);
  239.     glutInitWindowSize(256, 256);
  240.     glutInitWindowPosition(0, 0);
  241.     glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  242.     glutCreateWindow(argv[0]);
  243.     glutDisplayFunc(draw);
  244.     glutIdleFunc(draw); 
  245.     glutKeyboardFunc(key);
  246.     glutReshapeFunc(reshape);
  247.     init(defaultSphereMap);
  248.  
  249.     glutMainLoop();
  250.     return 0;
  251. }
  252.  
  253.